// 显示bmp图片=========================================================================================
#include "../inc/show_bmp.h"
#include "../inc/main.h"
#include "../inc/init_LCD.h"
#include "../inc/close_LCD.h"

// 初始化lcd==============================================================
void initLCD()
{
    struct LcdDevice *lcd_fd = init_lcd("/dev/fb0");
    lcd_addr = (int(*)[800])mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, lcd_fd->fd, 0);
}

// 显示bmp图片考虑对齐
int show_bmp(char *bmp_file_name, int x, int y)
{
  
    FILE *fp = fopen(bmp_file_name, "rb");
    if (fp == NULL)
    {
        printf("open bmp file error filename:%s\n", bmp_file_name);
        return -1;
    }

    struct BitMapFileHeader bmp_file_header;
    struct BitMapInfoHeader bmp_info_header;
    fread(&bmp_file_header, sizeof(struct BitMapFileHeader), 1, fp);
    fread(&bmp_info_header, sizeof(struct BitMapInfoHeader), 1, fp);

    int width = bmp_info_header.biWidth;
    int height = bmp_info_header.biHeight;

    // 计算每行的实际字节数，向上对齐到4的倍数
    int row_size = (width * 3 + 3) & ~3;

    // 分配内存用于存储图像数据
    unsigned char *bmp_buf = (unsigned char *)malloc(height * row_size);
    if (bmp_buf == NULL)
    {
        printf("malloc error\n");
        fclose(fp);
        return -1;
    }

    // 判断是24位bmp图片
    if (bmp_file_header.bfType == 19778 && bmp_info_header.biBitCount == 24)
    {
        fread(bmp_buf, row_size, height, fp); // 读取整个图像数据

        // 判断图片是否超出屏幕
        if (y + height > 480 || x + width > 800)
        {
            printf("bmp size is too big\n");
            free(bmp_buf);
            fclose(fp);
            return -1;
        }

        // 遍历图片数组 填充屏幕映射，倒置图像
        for (size_t row = 0; row < height; row++)
        {
            for (size_t col = 0; col < width; col++)
            {
                int pixel_index = (height - 1 - row) * row_size + col * 3; // 计算当前像素在 bmp_buf 中的索引，倒置行
                lcd_addr[row + y][col + x] = 0x00 << 24 | bmp_buf[pixel_index + 2] << 16 | bmp_buf[pixel_index + 1] << 8 | bmp_buf[pixel_index];
            }
        }

        // 释放内存
        free(bmp_buf);
        fclose(fp);
        return 0;
    }
    else
    {
        // 判断不是 24位bmp
        printf("not 24bit bmp name: %s\n", bmp_file_name);
    }

    // 释放内存并关闭文件
    free(bmp_buf);
    fclose(fp);
    return -1;
}
